package menu

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"wms/model"

	"wms/internal/svc"
	"wms/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type UpdateLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUpdateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateLogic {
	return &UpdateLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UpdateLogic) Update(req *types.MenuUpdateRequest) (resp *types.BaseResponse, err error) {
	resp = new(types.BaseResponse)
	if req.Id == req.ParentId {
		fmt.Printf("[Error]不能将菜单[%d]自身作为上级菜单\n", req.Id)
		resp.Code = http.StatusBadRequest
		resp.Msg = "不能将菜单自身作为上级菜单"
		return resp, nil
	}

	//1.父路由id是否存在
	if req.ParentId > 0 {
		var parent *model.Menu
		parent, err = l.svcCtx.MenuModel.FindOne(l.ctx, req.ParentId)
		switch err {
		case nil:
			if parent.Type != 1 {
				resp.Code = http.StatusBadRequest
				resp.Msg = "上级菜单必须是'菜单'类型"
				return resp, nil
			}
		case model.ErrNotFound:
			resp.Code = http.StatusBadRequest
			resp.Msg = "父路由不存在"
			return resp, nil
		default:
			fmt.Printf("[Error]查询父路由[%d]:%s\n", req.ParentId, err.Error())
			resp.Code = http.StatusBadRequest
			resp.Msg = "服务内部错误"
			return resp, nil
		}
	}

	//2.路由是否存在
	menu, err := l.svcCtx.MenuModel.FindOne(l.ctx, req.Id)
	switch err {
	case nil:
		fmt.Printf("[Debug]路由[%d]\n", req.Id)
		if menu.Type != req.Type {
			resp.Code = http.StatusBadRequest
			resp.Msg = "不支持修改菜单类型"
			return resp, nil
		}
	case model.ErrNotFound:
		resp.Code = http.StatusBadRequest
		resp.Msg = "路由不存在"
		return resp, nil
	default:
		fmt.Printf("[Error]查询路由[%d]:%s\n", req.ParentId, err.Error())
		resp.Code = http.StatusBadRequest
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	//3.路由是否重复：path、name
	if req.Path != menu.Path { //path查重
		fmt.Printf("req.Path=%s, menu.Path=%s\n", req.Path, menu.Path)
		var ms []model.Menu
		ms, err = l.svcCtx.MenuModel.FindByPage(l.ctx, fmt.Sprintf(" where path='%s'", req.Path))
		switch err {
		case nil:
		case model.ErrNotFound:
		default:
			fmt.Printf("[Error]查询路由路径[%s]:%s\n", req.Path, err.Error())
			resp.Code = http.StatusBadRequest
			resp.Msg = "服务内部错误"
			return resp, nil
		}

		if len(ms) > 0 {
			fmt.Printf("[Error]路由路径[%s]重复\n", req.Path)
			resp.Code = http.StatusBadRequest
			resp.Msg = "路由路径重复"
			return resp, nil
		}
	}

	//4.路由更新入库
	meta, err := json.Marshal(&types.Meta{
		Icon:       req.Icon,
		Transition: req.Transition,
		Hidden:     req.Hidden,
		Fixed:      req.Fixed,
		Perms:      req.Perms,
	})
	if err != nil {
		fmt.Printf("[Error]路由[%s]元信息解析:%s\n", req.Path, err.Error())
		resp.Code = http.StatusBadRequest
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	m := &model.Menu{
		Id:        req.Id,
		Type:      req.Type,
		SortId:    req.SortId,
		ParentId:  req.ParentId,
		Path:      strings.TrimSpace(req.Path),
		Name:      req.Name,
		Component: strings.TrimSpace(req.Component),
		Meta:      string(meta),
		Remark:    req.Remark,
	}

	err = l.svcCtx.MenuModel.Update(l.ctx, m)
	if err != nil {
		fmt.Printf("[Error]路由[%s]入库:%s\n", req.Path, err.Error())
		resp.Code = http.StatusBadRequest
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	resp.Code = http.StatusOK
	resp.Msg = "成功"
	return resp, nil
}
